
// Copyright 2010 William Malone (www.williammalone.com)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

var canvas;
var context;
var canvasWidth = 790;
var canvasHeight = 775;
var padding = [180,200,70,200];
var lineWidth = 8;

var colorBlack = new Object();
colorBlack.r = 0;
colorBlack.g = 0;
colorBlack.b = 0;

var color = [colorBlack];
var curColorIndex = 0;
var curColor = colorBlack;
var curFont = '';

var outlineImage = new Image();
var editImage = new Image();
var khungtranhImage = new Image();
var clickX = new Array();
var clickY = new Array();
var clickColor = new Array();
var clickTool = new Array();
var clickSize = new Array();
var clickDrag = new Array();
var history = new Array();
var paint = false;
var move = false;
var curTool = "crayon";
var curSize = "normal";
var drawingAreaX = 0;
var drawingAreaY = 0;
var drawingAreaWidth = 1000;
var drawingAreaHeight = 700;
var totalLoadResources = 2;
var curLoadResNum = 0;
var radius = 2;

var outlineLayerData;
var colorLayerData;
var tempLayerData;
var khungtranhLayerData;
var scale = 1;
var zoomIn = false;

var paths = new Array();
var shapeX, shapeY, shapeW, shapeH, shapeColor = '#01cafe';
/**
* Calls the redraw function after all neccessary resources are loaded.
*/
function resourceLoaded()
{
	if(++curLoadResNum >= totalLoadResources){
		redraw();
	}
}

/**
* Creates a canvas element, loads images, adds events, and draws the canvas for the first time.
*/
function prepareCanvas(editImageSrc, outlineImageSrc)
{
	if(editImageSrc==undefined||editImageSrc=='') editImageSrc = '';
	if(outlineImageSrc==undefined||outlineImageSrc=='') outlineImageSrc = '';
	outlineImage = new Image();
    editImage = new Image();
	khungtranhImage = new Image();
	//outlineLayerData = '';
	//colorLayerData = '';
	tempLayerData = '';
	//khungtranhLayerData = '';
	clickX = new Array();
	clickY = new Array();
	clickColor = new Array();
	clickTool = new Array();
	clickSize = new Array();
	clickDrag = new Array();
	// Create the canvas (Neccessary for IE because it doesn't know what a canvas element is)
	var canvasDiv = document.getElementById('canvasDiv');
	canvas = document.createElement('canvas');
	canvas.setAttribute('width', canvasWidth);
	canvas.setAttribute('height', canvasHeight);
	canvas.setAttribute('id', 'canvas');
	canvasDiv.appendChild(canvas);
	if(typeof G_vmlCanvasManager != 'undefined') {
		canvas = G_vmlCanvasManager.initElement(canvas);
	}
	context = canvas.getContext("2d"); // Grab the 2d canvas context
	// Note: The above code is a workaround for IE 8 and lower. Otherwise we could have used:
	//     context = document.getElementById('canvas').getContext("2d");
	
	// Load images
	// -----------
	khungtranhImage.onload = function() { resourceLoaded(); 
	};
	khungtranhImage.src = base_url + "img/imgbg.png";
	
	outlineImage.onload = function() { 
		// clearCanvasTransparent();
		// context.drawImage(khungtranhImage, 0, 0, drawingAreaWidth, drawingAreaHeight);
		// khungtranhLayerData = context.getImageData(0, 0, canvasWidth, canvasHeight);
		clearCanvasTransparent();
		// context.drawImage(outlineImage, drawingAreaX, drawingAreaY, drawingAreaWidth, drawingAreaHeight);
		// outlineLayerData = context.getImageData(0, 0, canvasWidth, canvasHeight);
		// clearCanvas();
		// context.beginPath();
  //       context.rect(padding[3], padding[0], canvasWidth - (padding[1]+padding[3]), canvasHeight - (padding[0]+padding[2]));
  //       context.lineWidth = 2;
  //       context.strokeStyle = '#fffeff';
  //       context.stroke();
		colorLayerData = context.getImageData(0, 0, canvasWidth, canvasHeight);
		resourceLoaded(); 
		
	};
	if(outlineImageSrc!='') outlineImage.src = outlineImageSrc;
	if(editImageSrc!='') editImage.src = editImageSrc;

	// Add mouse events
	// ----------------
	$('#canvas').mousedown(function(e)
	{
		e.originalEvent.preventDefault();
		if(toolChoose<=0) return;
		
		// Mouse down location
		ox = 0;oy = 0;radio=1;
		var offsetLeft =  $('#canvasDiv')[0].scrollLeft + ox;
		var offsetTop = $('#canvasDiv')[0].scrollTop + oy;

		var mouseX = e.pageX - this.offsetLeft - $('.container')[0].offsetLeft + offsetLeft;
		var mouseY = e.pageY - this.offsetTop + offsetTop;

		paint = true;
		addClick(mouseX, mouseY, false);
		redraw();
	});
	
	$('#canvas').mousemove(function(e){
		if(toolChoose<=0) return;
		if(paint==true){
			ox = 0;oy = 0;radio=1;
			var offsetLeft =  $('#canvasDiv')[0].scrollLeft + ox;
			var offsetTop = $('#canvasDiv')[0].scrollTop + oy;
			addClick(e.pageX - this.offsetLeft - $('.container')[0].offsetLeft + offsetLeft, e.pageY - this.offsetTop + offsetTop, true);
			redraw();
		}
	});
	
	$('#canvas').mouseup(function(e){
		if(toolChoose<=0) return;
	  	resetHistory();
		paint = false;
	  	redraw();
	});
	
	$('#canvas').mouseleave(function(e){
		if(toolChoose<=0) return;
		resetHistory();
		paint = false;
	});
}
function scaleImageData(imageData, scale) {
  var width = imageData.width;
  var height = imageData.height;
  var scaled = context.createImageData(width * scale, height * scale);

  for(var row = 0; row < height; row++) {
    for(var col = 0; col < width; col++) {
      var sourcePixel = [
        imageData.data[(row * width + col) * 4 + 0],
        imageData.data[(row * width + col) * 4 + 1],
        imageData.data[(row * width + col) * 4 + 2],
        imageData.data[(row * width + col) * 4 + 3]
      ];
      for(var y = 0; y < scale; y++) {
        var destRow = row * scale + y;
        for(var x = 0; x < scale; x++) {
          var destCol = col * scale + x;
          for(var i = 0; i < 4; i++) {
            scaled.data[(destRow * scaled.width + destCol) * 4 + i] =
              sourcePixel[i];
          }
        }
      }
    }
  }

  return scaled;
}
/**
* Adds a point to the drawing array.
* @param x
* @param y
* @param dragging
*/
function resetHistory(){
	clickX = new Array();
	clickY = new Array();
	clickColor = new Array();
	clickTool = new Array();
	clickSize = new Array();
	clickDrag = new Array();
}

function addClick(x, y, dragging)
{
	if(zoomIn) radio=1.5;
    else radio=1;
    x = x/radio;
    y = y/radio;
	if(curTool=='eraser'){
		var colorEraser = new Object();
		colorEraser.r = 255;
		colorEraser.g = 255;
		colorEraser.b = 255;
		clickColor.push(colorEraser);
	}
	else clickColor.push(curColor);
	clickX.push(x);
	clickY.push(y);
	clickTool.push(curTool);
	clickSize.push(curSize);
	clickDrag.push(dragging);
	clickRadius.push(radius);
	clickFillX.push(x);
	clickFillY.push(y);
    
    editing = true; 
    outcanvas = false; 
    if(clickX.length > 2){
    	clickColor.shift();
    	clickX.shift();
    	clickY.shift();
    	clickTool.shift();
    	clickSize.shift();
    	clickDrag.shift();
    }
}

/**
* Clears the canvas.
*/
function clearCanvasTransparent()
{
	context.clearRect(0, 0, canvasWidth, canvasHeight);
	// context.fillStyle = '#ffffff'; // Work around for Chrome
	// context.fillRect(0, 0, canvasWidth, canvasHeight); // Fill in the canvas with white
}
function clearCanvas()
{
	// context.clearRect(0, 0, canvasWidth, canvasHeight);
	context.fillStyle = '#ffffff'; // Work around for Chrome
	context.fillRect(0, 0, canvasWidth, canvasHeight); // Fill in the canvas with white
}

/**
* Redraws the canvas.
*/
function redraw()
{
	// Make sure required resources are loaded before redrawing
	if(curLoadResNum < totalLoadResources){ return; }

	clearCanvas();
   
	radio=1;
	$('#canvasDiv').attr('style','');

    $('#canvas').css('height',canvasHeight*radio+'px').css('width',canvasWidth*radio+'px');

	context.putImageData(colorLayerData, 0, 0);

	var i = 0;
	for(; i < clickX.length; i++)
	{	
		if(clickTool[i]=='marker'||clickTool[i] == "eraser"){	
			context.beginPath();
			if(clickDrag[i] && i){
				context.moveTo(clickX[i-1], clickY[i-1]);
				context.lineTo(clickX[i], clickY[i]);
				context.closePath();
			}else{
			    context.arc(clickX[i], clickY[i], clickRadius[i]/2, 0, 2 * Math.PI, false);
			    context.fillStyle = "rgba(" + clickColor[i].r + "," + clickColor[i].g + "," + clickColor[i].b + ",1)";
			    context.fill();
			    continue;
			}
			
			if(clickTool[i] == "eraser"){
				// context.globalCompositeOperation = "destination-out"; // To erase instead of draw over with white
				// context.strokeStyle = 'white';
				context.strokeStyle = "rgba(" + clickColor[i].r + "," + clickColor[i].g + "," + clickColor[i].b + ",1)";
			}else{
				//context.globalCompositeOperation = "source-over";	// To erase instead of draw over with white
				context.strokeStyle = "rgba(" + clickColor[i].r + "," + clickColor[i].g + "," + clickColor[i].b + ",1)";
			}
			context.lineJoin = "round";
			context.lineWidth = clickRadius[i];
			context.stroke();
		}else if(clickTool[i] == "crayon"){
			context.beginPath();
			for(m=0;m<clickRadius[i]*4;m++){
				if(clickDrag[i] && i){
					context.moveTo(clickX[i-1]+clickAirX[m], clickY[i-1]+clickAirY[m]);
					context.lineTo(clickX[i]+clickAirX[m], clickY[i]+clickAirY[m]);
					context.closePath();
				}else{
					context.beginPath();
					context.rect(clickX[i]+clickAirX[m],clickY[i]+clickAirY[m],1,1);
					context.fillStyle = "rgba(" + clickColor[i].r + "," + clickColor[i].g + "," + clickColor[i].b + ",0.2)";
			      	context.fill();
				}
				context.lineJoin = "round";
				context.strokeStyle = "rgba(" + clickColor[i].r + "," + clickColor[i].g + "," + clickColor[i].b + ",0.1)";
				context.lineWidth = 1;
				context.stroke();
		      }
		}
		
	}

	colorLayerData = context.getImageData(0, 0, canvasWidth, canvasHeight);
	// mergeLayer();
	// mergeLayerKhungTranh();
	if(colorLayerData){
		context.putImageData(colorLayerData, 0, 0);
		colorLayerData = context.getImageData(0, 0, canvasWidth, canvasHeight);
	}
	// if(!editne) context.drawImage(outlineImage, 0, 0, canvasWidth, canvasHeight);
	//context.globalCompositeOperation = "source-over";// To erase instead of draw over with white
	context.restore();
	context.globalAlpha = 1; // No IE support
}

function mergeLayer() {
  var width = outlineLayerData.width;
  var height = outlineLayerData.height;

  for(var row = 0; row < height; row++) {
    for(var col = 0; col < width; col++) {
      if(outlineLayerData.data[(row * width + col) * 4 + 3]!=0){
      	 colorLayerData.data[(row * width + col) * 4 + 0] = outlineLayerData.data[(row * width + col) * 4 + 0];
         colorLayerData.data[(row * width + col) * 4 + 1] = outlineLayerData.data[(row * width + col) * 4 + 1];
         colorLayerData.data[(row * width + col) * 4 + 2] = outlineLayerData.data[(row * width + col) * 4 + 2];
      }
    }
  }
}

function mergeLayerShape() {
  var width = tempLayerData.width;
  var height = tempLayerData.height;

  for(var row = 0; row < height; row++) {
    for(var col = 0; col < width; col++) {
      if(tempLayerData.data[(row * width + col) * 4 + 3]>3){
      	 colorLayerData.data[(row * width + col) * 4 + 0] = tempLayerData.data[(row * width + col) * 4 + 0];
         colorLayerData.data[(row * width + col) * 4 + 1] = tempLayerData.data[(row * width + col) * 4 + 1];
         colorLayerData.data[(row * width + col) * 4 + 2] = tempLayerData.data[(row * width + col) * 4 + 2];
      }
    }
  }
}

function mergeLayerKhungTranh() {
  var width = khungtranhLayerData.width;
  var height = khungtranhLayerData.height;

  for(var row = 0; row < height; row++) {
    for(var col = 0; col < width; col++) {
      if(khungtranhLayerData.data[(row * width + col) * 4 + 3]!=0){
      	 colorLayerData.data[(row * width + col) * 4 + 0] = khungtranhLayerData.data[(row * width + col) * 4 + 0];
         colorLayerData.data[(row * width + col) * 4 + 1] = khungtranhLayerData.data[(row * width + col) * 4 + 1];
         colorLayerData.data[(row * width + col) * 4 + 2] = khungtranhLayerData.data[(row * width + col) * 4 + 2];
      }
    }
  }
}